#include "swoole.h"

void* sw_shm_malloc(size_t size){
	swShareMemory object;
	void *mem;
	size += sizeof(swShareMemory);
	mem = swShareMemory_mmap_create(&object,size);

	if(mem == NULL){
		return NULL;
	}else{
		memcpy(mem,&object,sizeof(swShareMemory));
		return mem + sizeof(swShareMemory);
	}
}

void* sw_shm_calloc(size_t num, size_t _size){
	swShareMemory object;
	void *mem;
    void *ret_mem;
    int size = sizeof(swShareMemory) + (num * _size);
    mem = swShareMemory_mmap_create(&object, size);
    if (mem == NULL)
    {
        return NULL;
    }
    else
    {
        memcpy(mem, &object, sizeof(swShareMemory));
        ret_mem = mem + sizeof(swShareMemory);
        bzero(ret_mem, size - sizeof(swShareMemory));
        return ret_mem;
    }
}

void sw_shm_free(void *ptr){
	swShareMemory *object = ptr - sizeof(swShareMemory);
	swShareMemory_mmap_free(object);
}

void swShareMemory_mmap_free(swShareMemory *object){
	munmap(object->mem,object->size);
}

void *swShareMemory_mmap_create(swShareMemory *object,size_t size){
	int flag = MAP_SHARED | MAP_ANONYMOUS;
	void *mem;

	mem = mmap(NULL,size,PROT_READ | PROT_WRITE,flag,-1,0);
	if(mem == MAP_FAILED){
		printf("mmap error -- %s\n",strerror(errno));
		return NULL;
	}else{
		object->mem = mem;
		object->size = size;
		return mem;
	}
}
